package com.stu.vertx.hello.utils;


public class EncodeUtil
{
    String mvEncodeAlg = "";

    static final int DEC_MAX_PASSWORD_LENGTH = 8;

    public EncodeUtil(String pEncodingAlg)
    {
        mvEncodeAlg = pEncodingAlg;
    }

    public String decode(String pEncodedPassword)
    {
        if (mvEncodeAlg.equalsIgnoreCase("Base64"))
        {
            Base64 lvEncoder = new Base64();
            return new String(lvEncoder.decode(pEncodedPassword.toCharArray()));
        }
        else
        {
            return null;
        }
    }
    
    public byte[] decodeToByteArray(String pEncodedPassword)
    {
        if (mvEncodeAlg.equalsIgnoreCase("Base64"))
        {
            Base64 lvEncoder = new Base64();
            return lvEncoder.decode(pEncodedPassword.toCharArray());
        }
        else
        {
            return null;
        }
    }

    
    public String encode(byte[] pDate) throws NoSuchMethodException
    {
        if (pDate == null)
            return " ";
        else if (mvEncodeAlg.equalsIgnoreCase("Base64"))
        {
            Base64 lvEncoder = new Base64();
            return new String(lvEncoder.encode(pDate));
        }
        else
            throw new NoSuchMethodException("Encoding " + mvEncodeAlg + "not found!\nPlease contact system administrator.");
    }
    
    //BEGIN TASK #:TTL-GZ-clover_he-00002 2013-05-17 [BOCM] new function of corporateAction
    public String padStr(String pEncryptedPwd, String pReplaceStr, String pPosition, int pLength)
    {
            String lvReturnEncryptedPwd = new String();
            if(pEncryptedPwd !=null )
            {
                    if(pEncryptedPwd.length() != pLength)
                    {
                            if(pPosition != null && pPosition.trim().equals("R")) {
                            lvReturnEncryptedPwd = pEncryptedPwd;
                                    for(int i = pEncryptedPwd.length(); i < pLength; i++) {
                                    lvReturnEncryptedPwd = lvReturnEncryptedPwd.concat(pReplaceStr);
                            }
                    }
                            else {
                            lvReturnEncryptedPwd = pEncryptedPwd;
                                    for(int i = pEncryptedPwd.length(); i < pLength; i++) {
                                    lvReturnEncryptedPwd = pReplaceStr.concat(lvReturnEncryptedPwd);
                            }

                            }
                    }else{
                            lvReturnEncryptedPwd = pEncryptedPwd;
                    }
            }
            return lvReturnEncryptedPwd;
    }
    public String getFormattedPassword(String pEncryptedPwd, String pReplaceStr, String pPosition, int pLength)
    {
            String passWord1 = "                          ";
            if(pEncryptedPwd != null && pEncryptedPwd.length() == 16) {
                    passWord1 = padStr(pEncryptedPwd.substring(0, 12), pReplaceStr, pPosition, pLength);
            }
            else if(pEncryptedPwd != null && pEncryptedPwd.length() == 32) {
                    passWord1 = padStr(pEncryptedPwd.substring(0, 12) + pEncryptedPwd.substring(16, 28), pReplaceStr, pPosition, pLength);
            }
            return passWord1.toUpperCase();
    }
    //END TASK #:TTL-GZ-clover_he-00002 2013-05-17 [BOCM] new function of corporateAction

    private class Base64
    {
        //
        // code characters for values 0..63
        //
        private char[] alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".toCharArray();

        //
        // lookup table for converting base64 characters to value in range 0..63
        //
        private byte[] codes = new byte[256];

        {
            for (int i = 0; i < 256; i++)
            {
                codes[i] = -1;
            }
            for (int i = 'A'; i <= 'Z'; i++)
            {
                codes[i] = (byte) (i - 'A');
            }
            for (int i = 'a'; i <= 'z'; i++)
            {
                codes[i] = (byte) (26 + i - 'a');
            }
            for (int i = '0'; i <= '9'; i++)
            {
                codes[i] = (byte) (52 + i - '0');
            }
            codes['+'] = 62;
            codes['/'] = 63;
        }

        /**
         * Decodes a BASE-64 encoded stream to recover the original
         * data. White space before and after will be trimmed away,
         * but no other manipulation of the input will be performed.
         *
         * As of version 1.2 this method will properly handle input
         * containing junk characters (newlines and the like) rather
         * than throwing an error. It does this by pre-parsing the
         * input and generating from that a count of VALID input
         * characters.
         */
        public byte[] decode(char[] data)
        {

            // as our input could contain non-BASE64 data (newlines
            // and other silly human-prettifications) we must first
            // adjust our count of USABLE data so that...
            // (a) we don't misallocate the output array, and (b)
            // think that we miscalculated our data length just
            // because of extraneous throw-away junk
            int tempLen = data.length; // start with everything we've got
            for (int ix = 0; ix < data.length; ix++)
            {
                int value = codes[data[ix] & 0xFF]; // ignore
                if ( (value < 0) && (data[ix] != 61)) // 61 is the '=' symbol (a padding null byte)
                {
                    --tempLen; // aha, found some useless stuff to ignore!
                }
            }
            int len = ( (tempLen + 3) / 4) * 3; // calculate length based on what remains!
            if (tempLen > 0 && data[tempLen - 1] == '=')
            {
                --len;
            }
            if (tempLen > 1 && data[tempLen - 2] == '=')
            {
                --len;
            }
            byte[] out = new byte[len];

            int shift = 0; // # of excess bits stored in accum
            int accum = 0; // excess bits
            int index = 0;

            // we now go through the entire array (NOT using the 'tempLen' value)
            for (int ix = 0; ix < data.length; ix++)
            {
                int value = codes[data[ix] & 0xFF]; // ignore high byte of char
                if (value >= 0) // skip over non-code
                {
                    accum <<= 6; // bits shift up by 6 each time thru
                    shift += 6; // loop, with new bits being put in
                    accum |= value; // at the bottom.
                    if (shift >= 8) // whenever there are 8 or more shifted in,
                    {
                        shift -= 8; // write them out (from the top, leaving any
                        out[index++] = // excess at the bottom for next iteration.
                            (byte) ( (accum >> shift) & 0xff);
                    }
                }

                // we will also have skipped processing a padding null byte ('=') here;
                // these are used ONLY for padding to an even length and do not legally
                // occur as encoded data. for this reason we can ignore the fact that
                // no index++ operation occurs in that special case: the out[] array is
                // initialized to all-zero bytes to start with and that works to our
                // advantage in this combination.
            }

            // if there is STILL something wrong we just have to throw up now!
            if (index != out.length)
            {
                throw new Error("Miscalculated data length (wrote " + index + " instead of " + out.length + ")");
            }

            return out;
        }

        /**
         * returns an array of base64-encoded characters to represent the
         * passed data array.
         *
         * @param data the array of bytes to encode
         * @return base64-coded character array.
         */
        public char[] encode(byte[] data)
        {
            char[] out = new char[ ( (data.length + 2) / 3) * 4];

            //
            // 3 bytes encode to 4 chars.  Output is always an even
            // multiple of 4 characters.
            //
            for (int i = 0, index = 0; i < data.length; i += 3, index += 4)
            {
                boolean quad = false;
                boolean trip = false;

                int val = (0xFF & (int) data[i]);
                val <<= 8;
                if ( (i + 1) < data.length)
                {
                    val |= (0xFF & (int) data[i + 1]);
                    trip = true;
                }
                val <<= 8;
                if ( (i + 2) < data.length)
                {
                    val |= (0xFF & (int) data[i + 2]);
                    quad = true;
                }
                out[index + 3] = alphabet[ (quad ? (val & 0x3F) : 64)];
                val >>= 6;
                out[index + 2] = alphabet[ (trip ? (val & 0x3F) : 64)];
                val >>= 6;
                out[index + 1] = alphabet[val & 0x3F];
                val >>= 6;
                out[index + 0] = alphabet[val & 0x3F];
            }
            return out;
        }
    }

    private static class decEncrypt
    {
        public static int[][] g_intC = new int[17][28];
        public static int[][] g_intK = new int[17][48];
        public static int[][] g_intD = new int[17][28];
        final static int g_intPc_1_c[] =
            {57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36};
        final static int g_intP[] =
            {16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10, 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25};
        final static int g_intIP_tab[] =
            {58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, 62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8, 57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3, 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7};
        final static int g_int_IP_tab[] =
            {40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31, 38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29, 36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27, 34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25};
        final static int g_intPc_2[] =
            {14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10, 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2, 41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48, 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32};
        final static int g_intPc_1_d[] =
            {63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4};
        public final static int[][][] g_intSSS =
            {
            {
            {14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7}
            ,
            {0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8}
            ,
            {4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0}
            ,
            {15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}
        }
            ,
            {
            {
            15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10}
            ,
            {
            3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5}
            ,
            {
            0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15}
            ,
            {
            13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}
        }
            ,
            {
            {
            10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8}
            ,
            {
            13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1}
            ,
            {
            13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7}
            ,
            {
            1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}
        }
            ,
            {
            {
            7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15}
            ,
            {
            13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9}
            ,
            {
            10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4}
            ,
            {
            3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}
        }
            ,
            {
            {
            2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9}
            ,
            {
            14, 11, 2, 12,
            4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6}
            ,
            {
            4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14}
            ,
            {
            11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}
        }
            ,
            {
            {
            12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11}
            ,
            {
            10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8}
            ,
            {
            9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6}
            ,
            {
            4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}
        }
            ,
            {
            {
            4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1}
            ,
            {
            13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6}
            ,
            {
            1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2}
            ,
            {
            6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}
        }
            ,
            {
            {
            13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7}
            ,
            {
            1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2}
            ,
            {
            7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8}
            ,
            {
            2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}
        }
        };
        final public int[] g_intE_R =
            {32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 8, 9, 10, 11, 12, 13, 12, 13, 14, 15, 16, 17, 16, 17, 18, 19, 20, 21, 20, 21, 22, 23, 24, 25, 24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32, 1};
        private static String g_strPassWord;
        private static String g_strEncryPassWord = new String();
        private final String g_strKey = new String("1234567887654321");
        final public static int[] g_intExpandedKey =
            {0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1};
        public static int[] g_intBuffer = new int[64];
        public static int[] g_intTemp = new int[64];
        public static int[] g_intExpandedPassWord = new int[64];
        public static String g_strEncryKey;
        public final static int[] g_intLS_Count =
            {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1};
        public static int[] g_intll = new int[64];
        public static int[] g_intrr = new int[64];
        public static int[] g_intLL = new int[64];
        public static int[] g_intRR = new int[64];

        public decEncrypt()
        {
            setParameter("UUUIII");
        }

        public final void do_IP(int intTemp[])
        {
            int i, j;
            int tmp[] = new int[64];
            for (i = 0; i < 32; i++)
                tmp[i] = g_intrr[i];
            for (i = 32; i < 64; i++)
                tmp[i] = g_intll[i - 32];
            for (i = 0; i < 64; i++)
                intTemp[i] = tmp[g_int_IP_tab[i] - 1];
        }

        public final void doCompress0(int intTemp[])
        {
            int temp = 0;
            int ii, jj;
//	for (ii = 0; ii < 64; ++ii)
//	     System.out.print(intTemp[ii]);
            g_strEncryPassWord = " ";
            for (ii = 0; ii < 16; ++ii)
            {
                for (jj = 0; jj < 4; ++jj)
                    temp = temp + intTemp[ii * 4 + jj] * getPower(2, 3 - jj);
                    //String strTemp = new Character((char) temp).toString();
                String strTemp = Integer.toString(temp, 16);
                //System.out.println("fred" + strTemp);
                g_strEncryPassWord = (g_strEncryPassWord + strTemp);
                temp = 0;
            }
            g_strEncryPassWord = g_strEncryPassWord.substring(1);
//	System.out.print(g_strEncryPassWord);
        }

        public final void doDES()
        {
            setKeyStar();
            doEncrypt0();
        }

        final public void doEncrypt0()
        {
            int intTemp[] = new int[64];
            doIP();
            for (int ii = 1; ii < 17; ii++)
            {
                doF(ii);
                for (int jj = 0; jj < 32; jj++)
                {
                    g_intll[jj] = g_intLL[jj];
                    g_intrr[jj] = g_intRR[jj];
                }
            }
            do_IP(intTemp);
            doCompress0(intTemp);
        }

        final public void doExpandPassWord()
        {
            int ii, jj;
            int kk, hh;
            hh = 0;
            String strTmp = new String();
            for (ii = 0; ii < g_strPassWord.length(); ++ii)
            {
                if (Character.isDigit(g_strPassWord.charAt(ii)))
                    kk = Integer.valueOf(g_strPassWord.substring(ii, ii + 1)).intValue();
                else
                    kk = (int) g_strPassWord.charAt(ii);
                strTmp = Integer.toBinaryString(kk);
                strTmp = ("0000" + strTmp).substring(strTmp.length());
                strTmp = "1111" + strTmp;
                for (jj = 0; jj < 8; ++jj)
                {
                    hh = ii * 8 + jj;
                    g_intExpandedPassWord[hh] = Integer.valueOf(strTmp.substring(jj, jj + 1)).intValue();
                }
            }
            ++hh;
            //20050131 Michael Begin
            //for (kk = 0; kk < 16; ++kk)
            for (kk = 0; kk < g_intExpandedPassWord.length - hh; ++kk)
                g_intExpandedPassWord[hh + kk] = 0;
                //20050131 Michael End
                //	for (kk = 0; kk < 64; ++kk)
                //   System.out.print(g_intExpandedPassWord[kk]);
        }

        final public void doF(int n)
        {
            int ii;
            for (ii = 0; ii < 48; ii++)
                g_intBuffer[ii] = g_intrr[g_intE_R[ii] - 1];
            for (ii = 0; ii < 48; ii++)
            {
                g_intBuffer[ii] = (g_intBuffer[ii] + g_intK[n][ii]) & 1;
            }
            doS_Box();
            for (ii = 0; ii < 32; ii++)
                g_intBuffer[ii] = g_intTemp[g_intP[ii] - 1];
            for (ii = 0; ii < 32; ii++)
            {
                g_intRR[ii] = (g_intBuffer[ii] + g_intll[ii]) & 1;
            }
            for (ii = 0; ii < 32; ii++)
                g_intLL[ii] = g_intrr[ii];
        }

        final public void doIP()
        {
            int i;
            doExpandPassWord();
            for (i = 0; i < 32; i++)
                g_intll[i] = g_intExpandedPassWord[g_intIP_tab[i] - 1];
            for (i = 0; i < 32; i++)
                g_intrr[i] = g_intExpandedPassWord[g_intIP_tab[i + 32] - 1];
        }

        final public void doLS(String strType, int intII, int intCount)
        {
            int ii;
            if (strType.equals("C"))
            {
                for (ii = 0; ii < 28; ++ii)
                    g_intC[intII + 1][ii] = g_intC[intII][ (ii + intCount) % 28];
            }
            else
            {
                for (ii = 0; ii < 28; ++ii)
                    g_intD[intII + 1][ii] = g_intD[intII][ (ii + intCount) % 28];
            }
        }

        final public void doS_Box()
        {
            int i, j, k, m;
            int y, z;
            int iT;
            String strT1, strT2, strT, strChar;
            int ss[] = new int[8];
            m = 0;
            for (i = 0; i < 8; i++)
            {
                j = 6 * i;
                y = g_intBuffer[j] * 2 + g_intBuffer[j + 5];
                z = g_intBuffer[j + 1] * 8 + g_intBuffer[j + 2] * 4 + g_intBuffer[j + 3] * 2 + g_intBuffer[j + 4];
                strT2 = Integer.toBinaryString(g_intSSS[i][y][z]);
                strT1 = "0000" + strT2;
                strT = strT1.substring(strT2.length());
                for (k = 0; k < 4; k++)
                {
                    g_intTemp[m++] = Integer.valueOf(strT.substring(k, k + 1)).intValue();
                }
            }
        }

        public static void doSon(int jj)
        {
            int ii;
            int kk = 0;
            int intBuffer1[] = new int[56];
            for (ii = 0; ii < 28; ++ii)
                intBuffer1[ii] = g_intC[jj][ii];
            for (ii = 28; ii < 56; ++ii)
                intBuffer1[ii] = g_intD[jj][ii - 28];
            for (ii = 0; ii < 48; ++ii)
                g_intK[jj][ii] = intBuffer1[g_intPc_2[ii] - 1];
        }

        public final String getEncryPassWord()
        {
            return g_strEncryPassWord;
        }

        public final int getPower(int intBase, int intPower)
        {
            int ii;
            int jj;
            jj = 1;
            for (ii = 0; ii < intPower; ++ii)
                jj = jj * intBase;
            return jj;
        }

        final public void setKeyStar()
        {
            int ii, jj;
            for (ii = 0; ii < 28; ++ii)
                g_intC[0][ii] = g_intExpandedKey[g_intPc_1_c[ii] - 1];
            for (ii = 0; ii < 28; ++ii)
                g_intD[0][ii] = g_intExpandedKey[g_intPc_1_d[ii] - 1];
            for (jj = 0; jj < 16; ++jj)
            {
                doLS("C", jj, g_intLS_Count[jj]);
                doLS("D", jj, g_intLS_Count[jj]);
                doSon(jj + 1);
            }
        }

        public final void setParameter(String strIn)
        {
            g_strPassWord = strIn.trim();
            doDES();
        }

        /**
         * Insert the method's description here.
         * Creation date: (01/10/2001 3:23:46 PM)
         * @param password java.lang.String
         */
        public void setPassword(String password)
        {}
    }

}
